cmake_minimum_required(VERSION 2.8)

PROJECT(CGAL-bindings)

if(POLICY CMP0017)
# New policy in cmake-2.8.3
  cmake_policy(SET CMP0017 NEW)
endif()

if (POLICY CMP0042)
  # Set MACOSX_RPATH to ON
  cmake_policy (SET CMP0042 NEW)
endif()

option ( LINK_PYTHON_LIBRARY "Link against python libraries" ON )

include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/SWIG_CGAL_Macros.cmake)

find_package(CGAL QUIET COMPONENTS ImageIO)
find_package(SWIG REQUIRED)
option( BUILD_PYTHON "Build Python bindings" ON )
option( BUILD_JAVA "Build Java bindings" ON )
#set it to OFF by default while it is not fully tested and thus officially supported
option( BUILD_RUBY "Build Ruby bindings" OFF )

enable_testing ()
add_custom_target (tests)


if ( CGAL_FOUND )
  include( ${CGAL_USE_FILE} )

  if ("${CGAL_MAJOR_VERSION}" STREQUAL "4" AND "${CGAL_MINOR_VERSION}" STREQUAL "0")
  MESSAGE(STATUS "Using patches for CGAL-4.0")
  include_directories(BEFORE patches_for_CGAL_4.0/include)
  endif()

  if ("${CGAL_MAJOR_VERSION}" STREQUAL "4" AND "${CGAL_MINOR_VERSION}" STRLESS "2")
  MESSAGE(STATUS "Using patches from CGAL-4.2")
  include_directories(BEFORE patches_in_CGAL_4.2/include)
  endif()

  if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
    if(CMAKE_COMPILER_IS_GNUCXX)
      message (STATUS "Release mode with g++: using -fno-strict-aliasing flags")
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing")
    endif()
  endif()
  
  if (SWIG_FOUND)
    SET (UseSWIG ON)
    INCLUDE(${SWIG_USE_FILE})  

    SET(CMAKE_SWIG_FLAGS "-I${CMAKE_CURRENT_SOURCE_DIR}")
    include_directories(${CMAKE_CURRENT_SOURCE_DIR})

    if (${BUILD_RUBY})
      FIND_PACKAGE(Ruby)
      if (NOT RUBY_FOUND)  
        message(WARNING "Ruby has not been found, CGAL-bindings for Ruby will not be generated.")
        SET(BUILD_RUBY OFF)
      endif()
    else()  
      message(STATUS "BUILD_RUBY is set to OFF: no CGAL-bindings for Ruby will be generated.")
    endif()
    if (${BUILD_PYTHON})
      find_package(PythonInterp)
      FIND_PACKAGE(PythonLibs)
      if (NOT PYTHONLIBS_FOUND)
        SET(BUILD_PYTHON OFF)
        message(WARNING "Python has not been found, CGAL-bindings for Python will not be generated.")
      endif()
    else()  
      message(STATUS "BUILD_PYTHON is set to OFF: no CGAL-bindings for Python will be generated.")
    endif()
    if (${BUILD_JAVA})
      FIND_PACKAGE(JNI)
      if (NOT JAVA_INCLUDE_PATH)
        message(WARNING "JNI has not been found, CGAL-bindings for Java will not be generated.")
        SET(BUILD_JAVA OFF)
      endif()
    else()  
      message(STATUS "BUILD_JAVA is set to OFF: no CGAL-bindings for Java will be generated.")
    endif()

    SET (COMMON_LIBRARIES_PATH "${CMAKE_CURRENT_BINARY_DIR}/lib" CACHE PATH "Path where libraries common to all target languages are created.")

    if (RUBY_FOUND)
      SET (RUBY_OUTDIR_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/build-ruby" CACHE PATH "RUBY specific files output directory prefix: the CGAL directory will contain Ruby generated files and libraries.")
      LINK_DIRECTORIES("${RUBY_OUTDIR_PREFIX}/CGAL")
      MESSAGE(STATUS "Found Ruby libs.")
      MESSAGE(STATUS "CGAL-SWIG Ruby files and libraries will be written in ${RUBY_OUTDIR_PREFIX}/CGAL.")
    endif()
    if (BUILD_PYTHON)
      set (PYTHON_OUTDIR_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/build-python" CACHE PATH "PYTHON specific files output directory prefix: the CGAL directory will contain Python generated files and libraries.")
      configure_file (SWIG_CGAL/files/__init__.py "${PYTHON_OUTDIR_PREFIX}/CGAL/__init__.py" @ONLY)
      if (PYTHON_EXECUTABLE)
        file (GLOB python_files "${CMAKE_CURRENT_SOURCE_DIR}/examples/python/*.py")
        # exclude blocking matplotlib plotting example
        list (REMOVE_ITEM python_files ${CMAKE_CURRENT_SOURCE_DIR}/examples/python/polygonal_triangulation.py)
        foreach (TESTNAME_SRC ${python_files})
          get_filename_component (TESTNAME ${TESTNAME_SRC} NAME_WE)
          add_test (NAME pythontest_${TESTNAME} COMMAND ${PYTHON_EXECUTABLE} ${TESTNAME_SRC})
          set_tests_properties (pythontest_${TESTNAME} PROPERTIES ENVIRONMENT "PYTHONPATH=${PYTHON_OUTDIR_PREFIX};DATADIR=${CMAKE_CURRENT_SOURCE_DIR}/examples/data")
        endforeach ()

        if (NOT DEFINED PYTHON_MODULE_PATH)
          execute_process (COMMAND ${PYTHON_EXECUTABLE} -c "from distutils import sysconfig; print(sysconfig.get_python_lib(plat_specific=True, prefix='${CMAKE_INSTALL_PREFIX}'))"
                          OUTPUT_VARIABLE _ABS_PYTHON_MODULE_PATH
                          RESULT_VARIABLE _exit_code
                          OUTPUT_STRIP_TRAILING_WHITESPACE )

          if (NOT ${_exit_code})
            get_filename_component (_ABS_PYTHON_MODULE_PATH ${_ABS_PYTHON_MODULE_PATH} ABSOLUTE)
            file (RELATIVE_PATH _REL_PYTHON_MODULE_PATH ${CMAKE_INSTALL_PREFIX} ${_ABS_PYTHON_MODULE_PATH})
            set (PYTHON_MODULE_PATH ${_REL_PYTHON_MODULE_PATH})
          else ()
            message (SEND_ERROR "Could not run ${PYTHON_EXECUTABLE}")
          endif ()
        endif ()
      endif()
      install (FILES ${PYTHON_OUTDIR_PREFIX}/CGAL/__init__.py DESTINATION ${PYTHON_MODULE_PATH}/CGAL)

      LINK_DIRECTORIES("${PYTHON_OUTDIR_PREFIX}/CGAL")
      MESSAGE(STATUS "Found Python libs.")
      MESSAGE(STATUS "CGAL-SWIG Python files and libraries will be written in ${PYTHON_OUTDIR_PREFIX}/CGAL.")
    endif()
    if (BUILD_JAVA)
      SET (JAVA_OUTDIR_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/build-java/" CACHE PATH "Java specific files output directory prefix: Java files in CGAL directory, libraries in lib directory.")
      SET (JAVALIBPATH "${JAVA_OUTDIR_PREFIX}/lib")
      MESSAGE(STATUS "Found JNI: JNI include dirs ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2}.")
      MESSAGE(STATUS "CGAL-SWIG Java libraries and files will be respectively written in ${JAVALIBPATH} and ${JAVA_OUTDIR_PREFIX}/CGAL.")

      find_package (Java)
      if (JAVA_FOUND)
        file (GLOB java_files "${CMAKE_CURRENT_SOURCE_DIR}/examples/java/*.java")

        set (dependencies Mesh2Criteria Mesh3FacetCriteria Mesh3CellCriteria)
        set (dependencies_files)
        foreach (TESTNAME ${dependencies})
          list (APPEND dependencies_files ${CMAKE_CURRENT_SOURCE_DIR}/examples/java/${TESTNAME}.java)
        endforeach ()
        foreach (TESTNAME ${dependencies})
          list (REMOVE_ITEM java_files ${CMAKE_CURRENT_SOURCE_DIR}/examples/java/${TESTNAME}.java)
        endforeach ()

        foreach (TESTNAME_SRC ${java_files})
          get_filename_component(TESTNAME ${TESTNAME_SRC} NAME_WE)
          add_custom_target (javatest_${TESTNAME}
            COMMAND ${Java_JAVAC_EXECUTABLE} ${TESTNAME_SRC} ${dependencies_files} -d ${JAVA_OUTDIR_PREFIX}
            WORKING_DIRECTORY ${JAVA_OUTDIR_PREFIX})
          add_dependencies (tests javatest_${TESTNAME})
          add_test (NAME javatest_${TESTNAME} COMMAND ${Java_JAVA_EXECUTABLE} ${TESTNAME} WORKING_DIRECTORY ${JAVA_OUTDIR_PREFIX})
          set_tests_properties (javatest_${TESTNAME} PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${JAVALIBPATH}")
        endforeach ()

        # tests load files from source dir, eg: ../data/oni.xyz
        file (COPY examples/data DESTINATION ${JAVA_OUTDIR_PREFIX}/..)

      endif ()
    endif()

    MESSAGE(STATUS "Now adding packages")
    add_subdirectory(SWIG_CGAL/Kernel)
    add_subdirectory(SWIG_CGAL/Java)
    add_subdirectory(SWIG_CGAL/Triangulation_3)
    add_subdirectory(SWIG_CGAL/Triangulation_2)
    add_subdirectory(SWIG_CGAL/Polyhedron_3)
    add_subdirectory(SWIG_CGAL/Alpha_shape_2)
    add_subdirectory(SWIG_CGAL/Spatial_searching)
    add_subdirectory(SWIG_CGAL/AABB_tree)
    if (CGAL_ImageIO_FOUND)
      add_subdirectory(SWIG_CGAL/Surface_mesher)
    else()
      message(STATUS "NOTICE: CGAL imageIO has not be found, few bindings will not be compiled")
    endif()
    add_subdirectory(SWIG_CGAL/Mesh_3)
    add_subdirectory(SWIG_CGAL/Mesh_2)
    add_subdirectory(SWIG_CGAL/Interpolation)
    add_subdirectory(SWIG_CGAL/Convex_hull_2)
    add_subdirectory(SWIG_CGAL/Convex_hull_3)
    #filter Voronoi diagram bindings
    find_path(CGAL_VOR_BASIC_H "CGAL/Voronoi_diagram_2/basic.h"  ${CGAL_INCLUDE_DIRS} NO_DEFAULT_PATH)
    if ("${CGAL_VOR_BASIC_H}" STREQUAL "CGAL_VOR_BASIC_H-NOTFOUND")
      MESSAGE(STATUS "Using CGAL-4.0, Voronoi_diagram_2 bindings won't be available.")
    else()
      add_subdirectory(SWIG_CGAL/Voronoi_diagram_2)
    endif()
    add_subdirectory(SWIG_CGAL/HalfedgeDS)
    add_subdirectory(SWIG_CGAL/Point_set_processing_3)
    add_subdirectory(SWIG_CGAL/Box_intersection_d)
    add_subdirectory(SWIG_CGAL/Advancing_front_surface_reconstruction)

    if (CGAL_VERSION VERSION_GREATER 3.6)
      find_package(Eigen3 3.2.0) #(requires 3.2.0 or greater)
      if (EIGEN3_FOUND)
        include( ${EIGEN3_USE_FILE} )
        add_subdirectory(SWIG_CGAL/Polygon_mesh_processing)
      else()
        MESSAGE(STATUS "Eigen 3.2 or later was not found, Polygon_mesh_processing bindings will not be available")
      endif(EIGEN3_FOUND)
    endif()

    add_subdirectory(SWIG_CGAL/Polyline_simplification_2)

    if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/SWIG_CGAL/User_packages/CMakeLists.txt")
      MESSAGE(STATUS "Found SWIG_CGAL/User_packages/CMakeLists.txt, user packages will be built.")
      add_subdirectory(SWIG_CGAL/User_packages)
    endif()
  else()
    message(STATUS "NOTICE: CGAL-bindings requires the SWIG include files and binary program, and will not be compiled.")
  endif()
else()
    message(STATUS "NOTICE: CGAL-bindings requires the CGAL library, and will not be compiled.")
endif()
